home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d26 / cattest.arc / PROTOTYP.PAS < prev    next >
Pascal/Delphi Source File  |  1991-07-01  |  14KB  |  500 lines

  1. {$A+,B-,D+,E+,F+,G-,I+,L+,N-,O+,R-,S-,V+,X-}
  2. {$M 16384,0,655360}
  3.  
  4. {$UNDEF Watch_Student}   {used to record student answers to disk for "analysis"}
  5. {$UNDEF Overlaying}
  6.  
  7. {$IFNDEF Overlaying}
  8. PROGRAM {substitute next line}
  9. prototst;
  10.  
  11.  
  12. { an example of a simple question without formulas }
  13. {$ELSE}
  14. unit PROTOovr;
  15. interface
  16. function PROTO(VAR grade : Integer):Boolean;
  17. implementation
  18. {$ENDIF}
  19.  
  20. USES
  21. Crt,DOS,WIN,timestuf,UTILITY,EVAL3;
  22.  
  23. FUNCTION {substitute next line}
  24. PROTO
  25. (VAR grade : Integer)
  26. : Boolean; { when called, return True if properly answered
  27.                  returns False when help was used and the
  28.                  question resumed}
  29.  
  30.  
  31.  
  32.  
  33. TYPE 
  34.   DebugLinePtr = ^Debug_lines;
  35.   Debug_Lines = RECORD
  36.                   line : STRING; {these will be written into a debug window}
  37.                   next : DebugLinePtr;
  38.                 END;
  39.  
  40.   errorPtr =  ^Wrong_Answers;
  41.   Wrong_Answers = RECORD
  42.                     value : real; {each entry is a teacher chosen error value}
  43.                     remark : STRING; {each entry is a teacher chosen response}
  44.                     Next : errorPtr;
  45.                   END;
  46.  
  47.   TitleStrPtr = ^TitleStr;
  48.   WinRecPtr = ^WinRec;
  49.   WinRec = RECORD
  50.              Next: WinRecPtr;
  51.              State: WinState;
  52.              Title : TitleStrPtr;
  53.              TitleAttr, FrameAttr: Byte;
  54.              Buffer: Pointer;
  55.            END;
  56.  
  57. CONST 
  58.     variable : char = #0; { set to non character if numbers to be read }
  59.     tolerance : real = 0.1; { set to reasonable discriminatory level
  60.                               as fraction of true answer }
  61.  
  62.  
  63.  
  64.  
  65. VAR 
  66.   OutFile : TEXT;
  67.  
  68. CONST 
  69.     ProgName_String : STRING = {substitute next line}
  70. 'PROTO';
  71.  
  72. VAR 
  73.   SaveTextAttr : Byte;
  74.   OldQuestionFile : Text;
  75.   Choice_Line,
  76.   comment_string, {string for student responses }
  77.   answer : STRING; { Student response to main question }
  78.   true_answer,
  79.   Value : real;   { Returned value of Student response }
  80.   Err,ErrPos   : integer; {Required Error Flags for EVAL }
  81.   ErrMsg: STRING;
  82.   Problem_Right,
  83.   Question_Done : Boolean;
  84.   My_Choice : Char;
  85.   GenTempPtr,TempPtr,RootErrorPtr : errorPtr;
  86.   TempDebugLinePtr,GenTempDebugPtr,
  87.   RootDebugLinePtr : DebugLinePtr;
  88.   TopWindow : WinRecPtr;
  89.   WindowCount : Integer;
  90.   Color : Byte;
  91.   pswd : Char;
  92.   question2 : STRING;
  93.  
  94.  
  95.  
  96. PROCEDURE ActiveWindow(Active: Boolean);
  97. BEGIN
  98.   IF TopWindow <> NIL
  99.     THEN
  100.       BEGIN
  101.         UnFrameWin;
  102.         WITH TopWindow^ DO
  103.           IF Active
  104.             THEN
  105.               FrameWin(Title^, DoubleFrame, TitleAttr, FrameAttr)
  106.             ELSE
  107.               FrameWin(Title^, SingleFrame, FrameAttr, FrameAttr);
  108.       END;
  109. END;
  110.  
  111. PROCEDURE OpenWindow(X1, Y1, X2, Y2: Byte; T: TitleStr;
  112.                      TAttr, FAttr: Byte);
  113.  
  114. VAR 
  115.   W: WinRecPtr;
  116. BEGIN
  117.   GoToXY(38,1);WriteLn('WAIT');
  118.   ActiveWindow(False);
  119.   New(W);
  120.   WITH W^ DO
  121.     BEGIN
  122.       Next := TopWindow;
  123.       SaveWin(State);
  124.       GetMem(Title, Length(T) + 1);
  125.       Title^ := T;
  126.       TitleAttr := TAttr;
  127.       FrameAttr := FAttr;
  128.       Window(X1, Y1, X2, Y2);
  129.       GetMem(Buffer, WinSize);
  130.       ReadWin(Buffer^);
  131.       FrameWin(T, DoubleFrame, TAttr, FAttr);
  132.     END;
  133.   TopWindow := W;
  134.   Inc(WindowCount);
  135. END;
  136.  
  137. PROCEDURE CloseWindow;
  138.  
  139. VAR 
  140.   W: WinRecPtr;
  141. BEGIN
  142.   IF TopWindow <> NIL
  143.     THEN
  144.       BEGIN
  145.         W := TopWindow;
  146.         WITH W^ DO
  147.           BEGIN
  148.             UnFrameWin;
  149.             WriteWin(Buffer^);
  150.             FreeMem(Buffer, WinSize);
  151.             FreeMem(Title, Length(Title^) + 1);
  152.             RestoreWin(State);
  153.             TopWindow := Next;
  154.           END;
  155.         Dispose(W);
  156.         ActiveWindow(True);
  157.         Dec(WindowCount);
  158.         GoToXY(38,1);WriteLn('    ');
  159.       END;
  160. END;
  161.  
  162. PROCEDURE reverse(text_in:STRING);
  163. BEGIN
  164.   SaveTextAttr := TextAttr;
  165.   TextAttr := Black + LightGray*16;
  166.   OpenWindow(1,1,80,4,text_in,LightGray*16,LightGray);
  167.   TextAttr := LightGray;
  168.   ClrScr;
  169. END;
  170.  
  171. PROCEDURE Normal;
  172. BEGIN
  173.   CloseWindow;
  174.   TextAttr := SaveTextAttr;
  175. END;
  176.  
  177. PROCEDURE Help;
  178. BEGIN
  179.   Reverse('HELP');
  180.   Our_Write(1,1,'There is no help available for this question.');
  181.   Pause(1,2,'Press any key to continue.');
  182.   Normal;
  183. END;
  184.  
  185.  
  186.  
  187. FUNCTION Choice: Char;
  188.  
  189. VAR 
  190.   s : STRING;
  191. BEGIN
  192.   Reverse('MAIN MENU');
  193.   Our_Write(1,1,'[F1]:Calculator [F2]:Answer [F3]:Help [F4]:Comment [F5]:Next Question'  )
  194.   ;
  195.   Our_Write(1,2,'[F6]:Quit Exam '  );
  196.   Choice := Read_Key;
  197.   Normal;
  198. END;
  199.  
  200. FUNCTION Is_The_STUDENT_Answer_Right(prompt:STRING;
  201.                                      correct_value:real): boolean;
  202.  
  203. PROCEDURE Wrong_Answer;
  204.  
  205. VAR 
  206.   k_error: integer;
  207.   temp_value : real;
  208.   TEMP_REMARK : STRING;
  209. BEGIN
  210.   TempPtr := RootErrorPtr;
  211.   Reverse('Help after incorrect answer.');
  212.     WHILE TempPtr <> NIL DO
  213.       BEGIN
  214.  
  215.         IF abs(TempPtr^.value-value) <= abs(tolerance*true_answer)
  216.           THEN
  217.             BEGIN
  218.               Our_Write(1,1,TempPtr^.remark);
  219.               Pause(1,2,'Press any key to continue.');
  220.               Normal;
  221.               exit;
  222.             END;
  223.         { if we exhaust all guesses about the error, then do the following}
  224.         TempPtr := TempPtr^.Next;
  225.         END;
  226.   Our_write(1,1,'Unable to interpret your error. Returning to question.');
  227.   Pause(1,2,'Press any key to continue.');
  228.   Normal;
  229. END; {of Wrong_Answer}
  230.  
  231. BEGIN
  232.   Question_Done := False;
  233.   REPEAT
  234.     REPEAT
  235.       Reverse('ANSWER');
  236.       Our_Write(1,1,
  237.                      'Escape to leave, [0 thru 9, ., +, -, /, *, arrows], '+#27#217+
  238.                 ' key to compute.'
  239.                 );
  240.                 Our_Write(1,2,' ');
  241.       Read_Float_Masked
  242.                   (1,
  243.                    2,
  244.                    3, {number of digits}
  245.                    Prompt,
  246.                    False,
  247.                    value);
  248.       Normal;
  249.    {$IFDEF Watch_Student}
  250.       WriteLn(OutFile,Time_Stamp,'Answer input->',value);
  251.    {$ENDIF}
  252.       IF Escape_struck
  253.         THEN
  254.           BEGIN
  255.  
  256.             WHILE
  257.                   YesNo(1,2,'Do you want to abandon this question (y,n,Y,N)?') DO
  258.               BEGIN
  259.                 Is_The_STUDENT_Answer_Right := False;
  260.                       { student could not do this question }
  261.                 Question_Done := True;
  262.                       { abandon question, not necessarily Watch_Student }
  263.                 Grade := -1; {Proctor Convention}
  264.       {$IFDEF Watch_Student}
  265.                 WriteLn(OutFile,'Student abandoned problem');
  266.       {$ENDIF}
  267.                 exit;
  268.               END;
  269.           END;
  270.       UNTIL NOT Escape_Struck;
  271.  
  272.       IF abs(value - true_answer) <= abs(tolerance*true_answer)
  273.         THEN
  274.           BEGIN
  275.             Is_The_STUDENT_Answer_Right := True;
  276.             Question_Done := True;
  277.             exit;
  278.           END
  279.         ELSE
  280.           IF YesNo(1,2,'Do you want help?')
  281.             THEN
  282.               Wrong_Answer;
  283.  
  284.       UNTIL (Question_Done);
  285.  
  286. END {of Is_The_Student_Right};
  287.  
  288.  
  289. PROCEDURE Initialize;
  290. BEGIN
  291.   Randomize;
  292.   TopWindow := nil;
  293.   WindowCount := 0;
  294.   Question_Done := False;
  295.   Problem_Right := False;
  296.   {$IFDEF Watch_Student}
  297.   Assign(OutFile,ProgName_String+'.$$$');
  298.   if FileExists(ProgName_String+'$$$')
  299.     then Append(OutFile)
  300.       else ReWrite(OutFile);
  301.   {$ENDIF}
  302.  
  303. END {of Initialize};
  304.  
  305. PROCEDURE real_chooser(prompt:STRING;correct_answer:real);
  306.  
  307. VAR k_line : integer;
  308. BEGIN
  309.   REPEAT
  310.     My_Choice := Choice;
  311.     GoToXY(1,25);
  312.     ClrEol;
  313.     CASE My_Choice OF
  314.       PF1 : {Calculator}
  315.             BEGIN
  316.               Reverse('CALCULATOR');
  317.               Our_Write(1,1,
  318.                         'Escape to leave, [0 thru 9, ., +, -, /, *]'+#27#217+
  319.                         ' key to compute.'
  320.               );
  321.  
  322.               answer := Read_equation(
  323.                         1,2,80,'Enter an expression(max length = 80)',[]);
  324.               IF NOT Escape_struck
  325.                 THEN
  326.                   BEGIN
  327.                  {$IFDEF Watch_Student}
  328.                     WriteLn(OutFile,Time_Stamp,
  329.                             'Student expression follows:',answer);
  330.                  {$ENDIF}
  331.                     Evaluate(answer,Value,ErrPos,ErrMsg);
  332.                     IF ErrMsg <> 'O.K.'
  333.                       THEN
  334.                         BEGIN
  335.                           Our_Write
  336.                           (1,1,'There has been an error in interpreting your answer.'
  337.                           );
  338.                           Pause(1,2,'Press any key to continue.');
  339.                         END
  340.                       ELSE
  341.                         BEGIN
  342.                           GoToXY(1,1);
  343.                           Write('Calculator Result = ',Value);
  344.                           ClrEol;
  345.                  {$IFDEF Watch_Student}
  346.                           WriteLn(OutFile,Time_Stamp,
  347.                                   '*+-/*+-/ Calculator Result = ',Value);
  348.                  {$ENDIF}
  349.                           Pause(1,2,'Press any key to continue.');
  350.                         END;
  351.                   END;
  352.                Normal;
  353.             END;
  354.  
  355.       PF2 : {Enter an answer}
  356.             Problem_Right :=
  357.                              Is_The_STUDENT_Answer_Right('ANSWER = ',correct_answer);
  358.       PF3 : {Get Help}
  359.             Help;
  360.       PF4 : {Comment, this is not a full fledged editor, and may
  361.                        need improvement}
  362.             BEGIN
  363.               Reverse('COMMENT');
  364.               Our_Write(1,1,
  365.                         'Enter any characters (no editing available). End with ENTER.');
  366.               ReadLn(comment_string);
  367.               Normal;
  368.            {$IFDEF Watch_Student}
  369.               WriteLn(OutFile,Time_Stamp,
  370.                       'student comment: ', comment_string);
  371.             {$ENDIF}
  372.             END;
  373.       PF5 : {quit this question}
  374.             BEGIN
  375.           {$IFDEF Watch_Student}
  376.               WriteLn(OutFile,Time_Stamp,
  377.                       'Student abandoned problem, continuing to next.');
  378.               WriteLn(OutFile,'Closing file '+ProgName_String);
  379.               Close(OutFile);
  380.           {$ENDIF}
  381.               Question_Done := true;
  382.               Grade := -1; {this is the halt flag for terminating
  383.                          a question }
  384.             END;
  385.       PF6 : {quit the examination}
  386.             BEGIN
  387.           {$IFDEF Watch_Student}
  388.               WriteLn(OutFile,Time_Stamp,
  389.                       'Student abandoned examination.');
  390.               WriteLn(OutFile,'Closing file '+ProgName_string);
  391.               Close(OutFile);
  392.           {$ENDIF}
  393.               Question_Done := true;
  394.               Grade := -2; {this is the halt flag for terminating
  395.                          the examination }
  396.             END;
  397.       PF10 :
  398.              BEGIN {window with debug information}
  399.                SaveTextAttr := TextAttr;
  400.                TextAttr := Black + LightGray*16;
  401.                OpenWindow(2,10,78,24,'DEBUG',LightGray*16,LightGray);
  402.                TextAttr := LightGray;
  403.                ClrScr;
  404.                REPEAT
  405.                  pswd := Read_Key;
  406.                  UNTIL pswd = '\'; {change this if students discover it}
  407.                  TempDebugLinePtr :=  RootDebugLinePtr;
  408.                  while TempDebugLinePtr^.next <> NIL DO
  409.                  BEGIN
  410.                    WriteLn( TempDebugLinePtr^.line);
  411.                    TempDebugLinePtr := TempDebugLinePtr^.next;
  412.                  END;
  413.                  WriteLn( TempDebugLinePtr^.line); {last line}
  414.                  Pause(1,wherey+1,'Press a key to exit');
  415.                  Normal;
  416.              END;
  417.     END; {case}
  418.     UNTIL Question_Done;
  419.   END {of real_chooser};
  420.  
  421. {$I INITQUES.IN1} {all the exam specific material should be in here}
  422.  
  423. BEGIN      { MAIN question }
  424.   ClrScr;
  425.   question2 := '';
  426.   Initialize;
  427.   Init_question;
  428.  
  429.  
  430. { question posing section }
  431.  
  432.   PoseQuestion(5,question);
  433.   (* use the next only if  length of question is > 255 *)
  434.   PoseQuestion(7,question2);
  435.  
  436.   Real_Chooser(Choice_Line,true_answer);
  437.   {this problem requires a "real" answer'}
  438.  
  439.   IF (Question_Done AND Problem_Right)
  440.   THEN Grade := 100;
  441.  
  442.        {substitute next line}
  443.   PROTO
  444.         := Question_Done; {which is the right usage?
  445.                   pass grade back in case student
  446.                   quit the exam, remember that
  447.                   Problem_Right has the value true
  448.                   if problem was done correctly.}
  449.  
  450.    GenTempPtr := RootErrorPtr; {clean up errors from heap so that
  451.                                 no memory problems occur}
  452.    TempPtr := GenTempPtr^.Next;
  453.    Dispose(GenTempPtr);
  454.    WHILE TempPtr <> NIL DO
  455.      BEGIN
  456.        GenTempPtr := TempPtr^.Next;
  457.        Dispose(TempPtr);
  458.        TempPtr := GenTempPtr;
  459.      END;
  460.  
  461.    GenTempDebugPtr := RootDebugLinePtr; {clean up debug from heap so that
  462.                                 no memory problems occur}
  463.  
  464.    TempDebugLinePtr := GenTempDebugPtr^.Next;
  465.    Dispose(GenTempDebugPtr);
  466.    WHILE TempDebugLinePtr <> NIL DO
  467.      BEGIN
  468.        GenTempDebugPtr := TempDebugLinePtr^.Next;
  469.        Dispose(TempDebugLinePtr);
  470.        TempDebugLinePtr := GenTempDebugPtr;
  471.      END;
  472.   IF Problem_Right
  473.     THEN Pause(1,25,'Question Done Correctly, Press any key.')
  474.     ELSE Pause(1,25,'Exiting Question, Press any key.');
  475.     ClrScr;
  476.  
  477. END {substitute next line}
  478. {PROTO};
  479. {$IFNDEF Overlaying}
  480.  
  481. VAR
  482.     Done : Boolean;
  483.     Grade : Integer;
  484.  
  485. BEGIN {this is the MAIN entry for testing the question as a function}
  486.     Escape_struck := False;
  487.   REPEAT
  488.     IF Escape_struck
  489.       THEN noise(Acknowledge);
  490.     Done := {substitute next line}
  491.              PROTO
  492.              (grade);{this is a function call to the question begin debugged}
  493.     UNTIL Done;
  494.  
  495. {Record student's success now}
  496. {$ENDIF}
  497. END.
  498.  
  499.  
  500.